﻿Imports NHibernate
Imports NHibernate.Metadata
Imports System.Collections.Generic
Imports FrameworkNHibernate.Dal
Imports Spring.Transaction

Public MustInherit Class GenericsNHibernateDao(Of T)
    Implements IGenericDao(Of T)

    Private _sessionFactory As ISessionFactory
    Public Property SessionFactory() As ISessionFactory
        Get
            Return _sessionFactory
        End Get
        Set(ByVal value As ISessionFactory)
            _sessionFactory = value
        End Set
    End Property

    Protected ReadOnly Property CurrentSession() As ISession
        Get
            Return SessionFactory.GetCurrentSession()
        End Get
    End Property

    ''' <summary>
    ''' Este metodo está sendo usado para buscar os metadados de mapeamento da entidade do tipo T.
    ''' Isso é feito para lançar exceção de MappedExcpetion para casos em que se tenta usar uma entidade T que não esteja mapeada (ou por falta de xml de mapeamento ou por não adicionar o Assembly deste mapeamento no MappingAssemblies do DalSetup.xml
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub VerificaMapeamento()
        Try
            Dim classType As System.Type = GetType(T)
            Dim meta As IClassMetadata = SessionFactory.GetClassMetadata(classType)
        Catch ex As MappingException
            Throw New MappingException("exceção de MappedExcpetion para casos em que se tenta usar uma entidade T que não esteja mapeada (ou por falta de xml de mapeamento ou por não adicionar o Assembly deste mapeamento no MappingAssemblies do DalSetup.xml", ex)
        End Try
    End Sub

    ''' <summary>
    ''' Método genérico que busca todos os registros no BD, da entidade de tipo T.
    ''' </summary>
    ''' <returns>IList do tipo T</returns>
    ''' <remarks>Caso nada esteja sendo retornado e vc sabe que existem dados no BD, verifique se esta entidade está sendo mapeada com XML e se o Assembly ao qual este XML pertence está sendo declarado em DalSetup.xml no item MappingAssemblies.</remarks>
    <Interceptor.Transaction(TransactionPropagation.Supports, ReadOnly:=True)> _
    Public Function BuscarTodos() As IList(Of T) Implements IGenericDao(Of T).BuscarTodos
        VerificaMapeamento()
        Return CurrentSession.CreateCriteria(GetType(T)).List(Of T)()
    End Function

    <Interceptor.Transaction(TransactionPropagation.Supports, ReadOnly:=True)> _
    Public Function Buscar(ByRef id As Long) As T Implements IGenericDao(Of T).Buscar
        VerificaMapeamento()
        Return DirectCast(CurrentSession.Load(GetType(T), id), T)
    End Function

    <Interceptor.Transaction(TransactionPropagation.Required)> _
    Public Overridable Sub Apagar(ByRef entity As T) Implements IGenericDao(Of T).Apagar
        VerificaMapeamento()
        CurrentSession.Delete(entity)
    End Sub

    <Interceptor.Transaction(TransactionPropagation.Required)> _
    Public Sub SalvarOuAlterar(ByRef entity As T) Implements IGenericDao(Of T).SalvarOuAlterar
        VerificaMapeamento()
        CurrentSession.SaveOrUpdate(entity)
    End Sub

    <Interceptor.Transaction(TransactionPropagation.Required)> _
    Public Sub Salvar(ByRef entity As T) Implements IGenericDao(Of T).Salvar
        VerificaMapeamento()
        CurrentSession.Save(entity)
    End Sub

    <Interceptor.Transaction(TransactionPropagation.Required)> _
    Public Sub Alterar(ByRef entity As T) Implements IGenericDao(Of T).Alterar
        VerificaMapeamento()
        CurrentSession.Update(entity)
    End Sub

    Public Sub RemoverDaSessao(ByRef entities As List(Of T)) _
        Implements IGenericDao(Of T).RemoverDaSessao
        For Each _object As Object In entities
            CurrentSession.Evict(_object)
        Next
    End Sub

    Public Sub RemoverDaSessao(ByRef entity As T) _
        Implements IGenericDao(Of T).RemoverDaSessao
        CurrentSession.Evict(entity)
    End Sub

End Class

